#ifndef NETS_H
#define NETS_H

#include <string.h>
#include "Def.h"
#include "Nodes.h"

class PNets{
		
	public:
		// nets		
		vector<PCoarseNet*> nets; 
		vector<PCoarseNet*> nets_box; 
		
		//Destructor
		~PNets(){
			for(uint32_t i=0; i<nets.size(); ++i)
				delete nets[i];
			nets.clear();
		}
		
		// parser
		bool parse(string fileName){
			ifstream inp(fileName.c_str());
			if(!inp.is_open()){
				cerr<<"Can not open "<<fileName<<endl;
				exit(1);
			}
			
			int numPNets, numPins, degree;
			char line[1024];
			char name[256], direct[256];
			PCoarseNet *net;
			Node *node;
			NODE_ITERATOR it;
			
			for(int i=0; i<4; ++i)
				inp.getline(line, 1024);
				
			inp.getline(line, 1024);
			sscanf(line,"NumNets  :  %d", &numPNets);
			inp.getline(line, 1024);
			sscanf(line,"NumPins  :  %d", &numPins);
			inp.getline(line, 1024);
			
			cout<<"Number of nets: "<<numPNets<<endl;
			cout<<"Number of terminals: "<<numPins<<endl;
			
			nets.resize(numPNets);
			
			for(int i=0; i<numPNets; ++i){
				inp.getline(line, 1024);
				net = new PCoarseNet();
				sscanf(line,"NetDegree  :  %d    %s", &degree, name);
				net->name = name;
				nets[i] = net;
				net->terminals.resize(degree);
				net->directions.resize(degree);
				net->offsets.resize(degree);
				for(int j=0; j<degree; ++j){
					inp.getline(line, 1024);
					sscanf(line,"%s   %s  :     %f      %f", name, direct, &net->offsets[j].x, &net->offsets[j].y);
					node = new Node();
					node->name = name;
					it = nodes.nodes.find(node);
					if(it==nodes.nodes.end())
						it = nodes.terminals.find(node);
					if(it==nodes.terminals.end()){
						cerr<<"not found pin: "<<name<<endl;
						exit(1);
					}
					delete node;
					node = *it;
					net->terminals[j]=node;
					
					if(!strcmp(direct,"O"))
						net->directions[j] = O;
					else
						net->directions[j] = I;
				}	
			}
			inp.close();
			return true;
		}
		
		// set coordinates
		bool setCoordinates(void)
        {
			//set node centers
			NODE_ITERATOR it;
			Node *node;
			PCoarseNet *net;
			
			for(it=nodes.nodes.begin(); it!=nodes.nodes.end(); ++it){
				node = *it;
				node->setCenter();
			}
			for(it=nodes.terminals.begin(); it!=nodes.terminals.end(); ++it){
				node = *it;
				node->setCenter();
			}
			
			// set net coordinates
			for(uint32_t i=0; i<nets.size(); ++i){
				net = nets[i];
				net->points.resize(net->terminals.size());
				for(uint32_t j=0; j<net->terminals.size(); ++j){
					node = net->terminals[j];
					net->points[j].x = node->centerX + net->offsets[j].x;
					net->points[j].y = node->centerY + net->offsets[j].y;
					if(node->layer_id!=-1)
						net->points[j].z = node->layer_id;
					else
						net->points[j].z = 1;
				}
			}
			return true;
		}
						
        // create nets_box 
        void    create_nets_box ( Box box )
        {
            nets_box.clear();
            for ( int i = 0; i < nets.size(); i++ )
                if ( box.containNet(nets[i]) )
                    nets_box.push_back(nets[i]);
        }
					
	};	
				
	extern PNets pnets;
				
#endif

